package me.zhengjie.util;

import com.digitalpetri.modbus.master.ModbusTcpMaster;
import com.digitalpetri.modbus.requests.ReadHoldingRegistersRequest;
import com.digitalpetri.modbus.requests.WriteSingleRegisterRequest;
import com.digitalpetri.modbus.responses.ReadHoldingRegistersResponse;
import io.netty.buffer.ByteBuf;
import io.netty.util.ReferenceCountUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

@Slf4j
@Component
@RequiredArgsConstructor
public class TCPUtil {

    public static Integer readHoldingRegisters(ModbusTcpMaster master, int address){
        try {
            CompletableFuture<ReadHoldingRegistersResponse> future = master
                    .sendRequest(new ReadHoldingRegistersRequest(address, 1), 0);
            ReadHoldingRegistersResponse readHoldingRegistersResponse = future.get();
            if (readHoldingRegistersResponse != null) {
                ByteBuf buf = readHoldingRegistersResponse.getRegisters();
                int i = buf.readUnsignedShort();
                ReferenceCountUtil.release(readHoldingRegistersResponse);
                return i;
            }
            return null;
        } catch (InterruptedException | ExecutionException e) {
            log.error(e.getMessage());
            return null;
        }
    }

    public static String readHoldingRegistersString(ModbusTcpMaster master, int address){
        try {
            CompletableFuture<ReadHoldingRegistersResponse> future = master
                    .sendRequest(new ReadHoldingRegistersRequest(address, 1), 0);
            ReadHoldingRegistersResponse readHoldingRegistersResponse = future.get();
            if (readHoldingRegistersResponse != null) {
                ByteBuf buf = readHoldingRegistersResponse.getRegisters();
                byte[] bytes = new byte[2];
                buf.readBytes(bytes);
                ReferenceCountUtil.release(readHoldingRegistersResponse);
                return new String(bytes, StandardCharsets.UTF_8);
            }
            return null;
        } catch (InterruptedException | ExecutionException e) {
            log.error(e.getMessage());
            return null;
        }
    }

    public static void write(ModbusTcpMaster master, int address, int value){
        // 发送单个寄存器数据，一般是无符号16位值：比如10
        master.sendRequest(new WriteSingleRegisterRequest(address, value), 1);
    }
}
